App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

CropPicker.java
Go to the documentation of this file.
1 package mhr.appandroid.views;
2
3 import java.util.Arrays;
4
5 import mhr.appandroid.R;
6 import android.content.Context;
7 import android.graphics.Bitmap;
8 import android.graphics.BitmapFactory;
9 import android.graphics.Canvas;
10 import android.graphics.Paint;
11 import android.graphics.Path;
12 import android.graphics.Paint.Style;
13 import android.graphics.Path.Direction;
14 import android.graphics.RectF;
15 import android.graphics.drawable.ShapeDrawable;
16 import android.graphics.drawable.shapes.PathShape;
17 import android.graphics.Rect;
18 import android.util.AttributeSet;
19 import android.view.MotionEvent;
20 import android.view.View;
21
22 public class CropPicker extends View {
23
24 //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
25 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
26 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
27
28 public static interface CropPickerEventListener {
29 public void onStartTrackingCrop(CropPicker p);
30 public void onCropChanged(CropPicker p);
31 public void onStopTrackingCrop(CropPicker p);
32 }
33
34
35 //===== FIELDS ==============================================================================================================================//
36 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
37 protected Bitmap cPressed;
38 protected Bitmap cNormal;
39 protected Rect cRect;
40
41 protected Paint bgPaint;
42 protected Paint lnPaint;
43
44 protected Rect[] curs;
45 protected Rect selCur = null;
46 protected int selCutIndex;
47
48 protected RectF crop;
49 protected RectF maxRect;
50
51 protected float lastX;
52 protected float lastY;
53
54 protected int cWidth;
55 protected int cHeight;
56 protected int cXCenter;
57 protected int cYCenter;
58
59 protected CropPickerEventListener listener = null;
60
61 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
62
63 //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
64 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
65 protected void init() {
66 setLayerType(View.LAYER_TYPE_SOFTWARE, null);
67 cPressed = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_pressed_bw);
68 cNormal = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_normal_bw);
69
70 bgPaint = new Paint();
71 bgPaint.setColor(0xFF545454);
72
73 lnPaint = new Paint();
74 lnPaint.setColor(0xFFFFFFFF);
75 lnPaint.setStyle(Style.STROKE);
76 lnPaint.setStrokeWidth(5);
77 lnPaint.setAntiAlias(true);
78
79 cWidth = cNormal.getWidth();
80 cHeight = cNormal.getHeight();
81
82 cXCenter = cWidth / 2;
83 cYCenter = cHeight / 2;
84
85 cRect = new Rect(0, 0, cNormal.getWidth(), cNormal.getHeight());
86 }
87 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
88 public CropPicker(Context context) {
89 super(context);
90 init();
91 }
92
93 public CropPicker(Context context, AttributeSet attrs) {
94 super(context, attrs);
95 init();
96 }
97
98 public CropPicker(Context context, AttributeSet attrs, int defStyle) {
99 super(context, attrs, defStyle);
100 init();
101 }
102
103 //===== METHODS =============================================================================================================================//
104 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
105 protected void updateRects() {
106
107 Rect r;
108
109 r = curs[0];
110 r.left = (int)(crop.left - cXCenter);
111 r.top = (int)(crop.top - cYCenter);
112 r.right = (int)(crop.left + cWidth - cXCenter);
113 r.bottom = (int)(crop.top + cHeight - cYCenter);
114
115 r = curs[1];
116 r.left = (int)(crop.right - cXCenter);
117 r.top = (int)(crop.top - cYCenter);
118 r.right = (int)(crop.right + cWidth - cXCenter);
119 r.bottom = (int)(crop.top + cHeight - cYCenter);
120
121 r = curs[2];
122 r.left = (int)(crop.left - cXCenter);
123 r.top = (int)(crop.bottom - cYCenter);
124 r.right = (int)(crop.left + cWidth - cXCenter);
125 r.bottom = (int)(crop.bottom + cHeight - cYCenter);
126
127 r = curs[3];
128 r.left = (int)(crop.right - cXCenter);
129 r.top = (int)(crop.bottom - cYCenter);
130 r.right = (int)(crop.right + cWidth - cXCenter);
131 r.bottom = (int)(crop.bottom + cHeight - cYCenter);
132 }
133
134 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
135
136 public void setListener(CropPickerEventListener l) {
137 listener = l;
138 }
139
140 public RectF getCrop() {
141 return new RectF(crop);
142 }
143
144 public void setCrop(RectF crop) {
145 this.crop = crop;
146 invalidate();
147 }
148
149 public void resetCrop() {
150 crop = new RectF(maxRect.right / 4, maxRect.bottom / 4, 3 * maxRect.right / 4, 3 * maxRect.bottom / 4);
151 invalidate();
152 }
153 //===== CALLBACKS ===========================================================================================================================//
154
155 @Override
156 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
157 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
158 }
159
161 @Override
162 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
163 super.onSizeChanged(w, h, oldw, oldh);
164
165 maxRect = new RectF(0, 0, w, h);
166 crop = new RectF(w / 4, h / 4, 3 * w / 4, 3 * h / 4);
167
168 curs = new Rect[] { new Rect(), new Rect(),new Rect(),new Rect() };
169 }
170
172 @Override
173 protected void onDraw(Canvas canvas) {
174 updateRects();
175 canvas.drawColor(0x00000000);
176
177 Path pth = new Path();
178 pth.addRect(0, 0, maxRect.right, crop.top, Direction.CW);
179 pth.addRect(0, crop.top, crop.left, crop.bottom, Direction.CW);
180 pth.addRect(crop.right, crop.top, maxRect.right, crop.bottom, Direction.CW);
181 pth.addRect(0, crop.bottom, maxRect.right, maxRect.bottom, Direction.CW);
182 ShapeDrawable sdr = new ShapeDrawable(new PathShape(pth, maxRect.width(), maxRect.height()));
183 Paint paint = sdr.getPaint();
184 paint.setStyle(Style.FILL);
185 paint.setColor(0xAA000000);
186 sdr.setBounds((int)maxRect.left, (int)maxRect.top, (int)maxRect.right, (int)maxRect.bottom);
187 sdr.draw(canvas);
188
189 canvas.drawLines(new float[] {
190 crop.left, crop.top, crop.right, crop.top,
191 crop.left, crop.top, crop.left, crop.bottom,
192 crop.left, crop.bottom, crop.right, crop.bottom,
193 crop.right, crop.top, crop.right, crop.bottom,
194 }, lnPaint);
195
196 for (Rect r : curs) {
197 if (r == selCur) {
198 canvas.drawBitmap(cPressed, null, r, null);
199 } else {
200 canvas.drawBitmap(cNormal, null, r, null);
201 }
202 }
203 }
204
205 @Override
206 public boolean onTouchEvent(MotionEvent ev) {
207 float x = ev.getX();
208 float y = ev.getY();
209
210 switch (ev.getAction()) {
211 case MotionEvent.ACTION_DOWN:
212 for (int i = 0; i < curs.length; i++) {
213 if (curs[i].contains((int)x, (int)y)) {
214 selCur = curs[i];
215 selCutIndex = i;
216 break;
217 }
218 }
219 if (selCur != null) {
220 lastX = x;
221 lastY = y;
222 if (listener != null) {
223 listener.onStartTrackingCrop(this);
224 }
225 }
226 break;
227 case MotionEvent.ACTION_MOVE:
228 if (selCur != null) {
229 switch (selCutIndex) {
230 case 0:
231 crop.left += x - lastX;
232 crop.left = (crop.left < crop.right) ? crop.left : crop.right;
233 crop.top += y - lastY;
234 crop.top = (crop.top < crop.bottom) ? crop.top : crop.bottom;
235 break;
236 case 1:
237 crop.right += x - lastX;
238 crop.right = (crop.left < crop.right) ? crop.right : crop.left;
239 crop.top += y - lastY;
240 crop.top = (crop.top < crop.bottom) ? crop.top : crop.bottom;
241 break;
242 case 2:
243 crop.left += x - lastX;
244 crop.left = (crop.left < crop.right) ? crop.left : crop.right;
245 crop.bottom += y - lastY;
246 crop.bottom = (crop.top < crop.bottom) ? crop.bottom : crop.top;
247 break;
248 case 3:
249 crop.right += x - lastX;
250 crop.right = (crop.left < crop.right) ? crop.right : crop.left;
251 crop.bottom += y - lastY;
252 crop.bottom = (crop.top < crop.bottom) ? crop.bottom : crop.top;
253 break;
254 default:
255 break;
256 }
257 lastX = x;
258 lastY = y;
259
260 crop.setIntersect(maxRect, crop);
261
262 if (listener != null) {
263 listener.onCropChanged(this);
264 }
265 invalidate();
266 }
267 break;
268 case MotionEvent.ACTION_UP:
269 if (selCur != null) {
270 selCur = null;
271 if (listener != null) {
272 listener.onStopTrackingCrop(this);
273 }
274 invalidate();
275 }
276 break;
277 }
278 return true;
279 }
280 }