App

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

- File List
- File Members

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